package com.personal.common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.personal.common.exception.CommonException;

public class HttpClientUtil {
	
	private static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);



	/**
	 * 执行一个HTTP GET请求，返回请求响应的HTML
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param queryString
	 *            请求的查询参数,可以为null
	 * @return 返回请求响应的HTML
	 */
	public static String doGet(String url, Map<String, String> params) {
		url = buildURL(url, params);
		log.info(Utils.joinString("请求get请求：[", url, "] 开始-->"));
		String response = null;
		HttpClient client = new HttpClient();

		HttpMethod method = new GetMethod(url);
		// 连接超时
		client.getHttpConnectionManager()
				.getParams()
				.setConnectionTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("connection_timeout")));
		// 读取超时：
		client.getHttpConnectionManager()
				.getParams()
				.setSoTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("so_timeout")));
		HttpClientParams httpClientParams = new HttpClientParams();
		// 实际超时时间以setConnectionManagerTimeout为准
		httpClientParams.setConnectionManagerTimeout(Integer
				.valueOf(Constants.DEPLOY_PROPERTIES
						.getValue("connection_manager_timeout")));
		httpClientParams.setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));
		client.setParams(httpClientParams);
		try {
			client.executeMethod(method);
			if (method.getStatusCode() == HttpStatus.SC_OK) {
				// response = method.getResponseBodyAsString();
				response = getResponseString(method);
			}
		}catch (IOException e) {
			log.error("执行HTTP Get请求" + url + "时，发生异常！", e);
		} finally {
			log.info("请求get请求结束-->");
			method.releaseConnection();
		}
		return response;
	}




	/**
	 * 执行一个HTTP POST请求，返回请求响应的HTML
	 * 
	 * @param url
	 *            请求的URL地址
	 * @param params
	 *            请求的查询参数,可以为null
	 * @return 返回请求响应的HTML
	 */
	public static String doPost(String url, Map<String, String> params) throws CommonException {
		if (null == params) {
			params = new HashMap<String, String>();
		}
		String response = null;

		HttpClient client = new HttpClient();
		// 使用代理
		if ("1".equals(Constants.DEPLOY_PROPERTIES.getValue("proxy_open_flag"))) {
			// 设置代理服务器的ip地址和端口
			client.getHostConfiguration().setProxy(
					Constants.DEPLOY_PROPERTIES.getValue("proxy_positive_ip"),
					Integer.valueOf(Constants.DEPLOY_PROPERTIES
							.getValue("proxy_positive_port")));
			// 使用抢先认证
			client.getParams().setAuthenticationPreemptive(true);
		}

		PostMethod post = new PostMethod(url);

		post.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded;charset=utf-8");
		// 连接超时
		client.getHttpConnectionManager()
				.getParams()
				.setConnectionTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("connection_timeout")));
		// 读取超时：
		client.getHttpConnectionManager()
				.getParams()
				.setSoTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("so_timeout")));
		HttpClientParams httpClientParams = new HttpClientParams();
		// 实际超时时间以setConnectionManagerTimeout为准
		httpClientParams.setConnectionManagerTimeout(Integer
				.valueOf(Constants.DEPLOY_PROPERTIES
						.getValue("connection_manager_timeout")));
		httpClientParams.setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));
		client.setParams(httpClientParams);

		log.info(Utils.joinString("请求post请求：[", url, "] 开始-->"));

		// 设置Http Post数据
		NameValuePair[] values = new NameValuePair[params.size()];
		int index = 0;
		for (Map.Entry<String, String> entry : params.entrySet()) {
			values[index++] = new NameValuePair(entry.getKey(),
					entry.getValue());
		}
		post.setRequestBody(values);
		try {

			client.executeMethod(post);
			if (post.getStatusCode() == HttpStatus.SC_OK) {
				// response = post.getResponseBodyAsString();
				response = getResponseString(post);
			}
		} catch (IOException e) {
			log.error("执行HTTP Post请求" + url + "时，发生异常！", e);
		} finally {
			log.debug("请求post请求结束-->" + response);
			post.releaseConnection();
		}
		log.debug("返回 : " + response);
		return response;
	}


	public static String doPost(String url, String params){
		String response = null;

		HttpClient client = new HttpClient();
		// 使用代理
		if ("1".equals(Constants.DEPLOY_PROPERTIES.getValue("proxy_open_flag"))) {
			// 设置代理服务器的ip地址和端口
			client.getHostConfiguration().setProxy(
					Constants.DEPLOY_PROPERTIES.getValue("proxy_positive_ip"),
					Integer.valueOf(Constants.DEPLOY_PROPERTIES
							.getValue("proxy_positive_port")));
			// 使用抢先认证
			client.getParams().setAuthenticationPreemptive(true);
		}

		PostMethod post = new PostMethod(url);
		post.setRequestHeader("Content-Type",
				"application/x-www-form-urlencoded;charset=utf-8");
		// 连接超时
		client.getHttpConnectionManager()
				.getParams()
				.setConnectionTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("connection_timeout")));
		// 读取超时：
		client.getHttpConnectionManager()
				.getParams()
				.setSoTimeout(
						Integer.valueOf(Constants.DEPLOY_PROPERTIES
								.getValue("so_timeout")));
		HttpClientParams httpClientParams = new HttpClientParams();
		// 实际超时时间以setConnectionManagerTimeout为准
		httpClientParams.setConnectionManagerTimeout(Integer
				.valueOf(Constants.DEPLOY_PROPERTIES
						.getValue("connection_manager_timeout")));
		httpClientParams.setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler(0, false));
		client.setParams(httpClientParams);
		log.info(Utils.joinString("请求post请求：[", url, "] 开始-->"));

		try {
			post.setRequestEntity(new StringRequestEntity(params, null, "utf-8"));
			client.executeMethod(post);
			if (post.getStatusCode() == HttpStatus.SC_OK) {
				response = getResponseString(post);
				
			}
		} catch (IOException e) {
			log.error("执行HTTP Post请求" + url + "时，发生异常！", e);
		} finally {
			log.info("请求post请求结束-->");
			post.releaseConnection();
		}
		return response;
	}
	/**
	 * 生成URL
	 * 
	 * @param url
	 * @param paraMap
	 * @return
	 */
	protected static String buildURL(String url, Map<String, String> paramMap) {
		if (paramMap == null || paramMap.isEmpty()) {
			return url;
		}
		if (StringUtils.isEmpty(url)) {
			return url;
		}
		StringBuffer sb = new StringBuffer();
		for (Iterator<String> iterator = paramMap.keySet().iterator(); iterator.hasNext();) {
			String key = (String) iterator.next();
			sb.append(key).append("=").append(paramMap.get(key));
			if (iterator.hasNext()) {
				sb.append("&");
			}
		}
		String paraStr = sb.toString();
		StringBuffer buffer = new StringBuffer();

		buffer.append(url);
		if (url.indexOf("?") != -1) {
			if (url.indexOf("?") == url.length() - 1) {
				buffer.append(paraStr);
			} else {
				buffer.append("&").append(paraStr);
			}
		} else {
			buffer.append("?").append(paraStr);
		}
		return buffer.toString();
	}

	/**
	 * post.getResponseBodyAsString() 如果返回的头信息没有指定长度或长度大于1M则抛出异常，此方法可以解决
	 * 
	 * @param method
	 * @return
	 * @throws IOException
	 */
	private static String getResponseString(HttpMethod method)
			throws IOException {
		InputStream inputStream = method.getResponseBodyAsStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(
				inputStream, Constants.ENCODING_UTF8));
		StringBuffer stringBuffer = new StringBuffer();
		String str = "";
		while ((str = br.readLine()) != null) {
			stringBuffer.append(str);
		}

		return stringBuffer.toString();
	}
}
